package com.oliver.proxy.midjourney.domain.service;

import com.oliver.proxy.midjourney.domain.aggregate.TaskAggregate;
import com.oliver.proxy.midjourney.domain.entity.InsertPoint;
import com.oliver.proxy.midjourney.domain.exception.TaskValidationException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class TaskDomainService {
    
    public void validateInsertPoints(TaskAggregate taskAggregate, Map<String, String> insertPoints) {
        if (!taskAggregate.isTypeZero()) {
            return;
        }

        String prompt = taskAggregate.getTaskList().getTaskPrompt();
        List<Integer> placeholders = extractPlaceholders(prompt);

        validatePlaceholdersAndInsertPoints(placeholders, insertPoints);
    }

    private List<Integer> extractPlaceholders(String prompt) {
        Pattern pattern = Pattern.compile("\\{(\\d+)\\}");
        Matcher matcher = pattern.matcher(prompt);
        List<Integer> placeholders = new ArrayList<>();
        
        while (matcher.find()) {
            placeholders.add(Integer.parseInt(matcher.group(1)));
        }
        
        return placeholders;
    }

    private void validatePlaceholdersAndInsertPoints(List<Integer> placeholders, Map<String, String> insertPoints) {
        if (insertPoints == null || insertPoints.isEmpty()) {
            if (!placeholders.isEmpty()) {
                throw new TaskValidationException("Insert points are required for prompt with placeholders");
            }
            return;
        }

        if (placeholders.size() != insertPoints.size()) {
            throw new TaskValidationException(
                String.format("Number of placeholders (%d) does not match number of insert points (%d)",
                    placeholders.size(), insertPoints.size())
            );
        }

        for (int i = 0; i < placeholders.size(); i++) {
            String key = "insert" + (i + 1);
            if (!insertPoints.containsKey(key)) {
                throw new TaskValidationException("Missing insert point: " + key);
            }
        }
    }

    public List<InsertPoint> createInsertPoints(Long taskId, Map<String, String> insertPoints) {
        List<InsertPoint> result = new ArrayList<>();
        insertPoints.forEach((key, content) -> {
            int index = Integer.parseInt(key.substring(6)) - 1;
            InsertPoint insertPoint = new InsertPoint();
            insertPoint.setTaskId(taskId);
            insertPoint.setPoint("{" + index + "}");
            insertPoint.setContent(content);
            result.add(insertPoint);
        });
        return result;
    }
}